﻿#include "GLLInc.h"
#include "GLLGameApp.h"
#include "GLLOSApp.h"
#include "GLLGameState.h"
#include "GLLInput.h"
#include "GLLVirtualWorld.h"
#include "GLLResMgr.h"
#include "GLLConsole.h"
#include "GLLVirtualWorld.h"
#include "GLLTheSystem.h"

#include "GLLLevel.h"
#include "GLLLevelManager.h"

namespace GLL
{
	class NullGameState : public GameState
	{
		virtual bool Ok2ExitGame(){return false;}
		virtual bool OnExitGame(){return true;}
	}nullstate;

	GameApp::GameApp( bool console )
	{
		_Paused = true;
		_Exit = false;
		_hasConsole = console;
		_3DWorld = 0;
		_currentGS = &nullstate;
		_input = 0;
		_resMgr = 0;
		_console = 0;
		_timeStamp = 0;
		_FPS = 0;
		_FPSAve = 0;
		SetMaxFPS(100);
	}

	Console* GameApp::_new_Console()
	{
		return GLL_NEW Console();
	}

	ResMgr* GameApp::_new_ResMgr()
	{
		return GLL_NEW ResMgr();
	}

	Input* GameApp::_new_Input()
	{
		return GLL_NEW Input();
	}

	VirtualWorld* GameApp::_new_VirtualWorld()
	{
		return GLL_NEW VirtualWorld();
	}

	GameApp::~GameApp( void )
	{
	}

	void GameApp::ChangeState( GameState& gameState )
	{
		//先从上一个状态中退出
		_currentGS->OnExit();
		//再进入状态
		gameState.OnEnter(_currentGS);
		_currentGS = &gameState;
	}

	void GameApp::Init()
	{
		if(_hasConsole)
		{
			_console = _new_Console();
			if(!_console){
				GLL_Throw("Creating Console failed");
			}
			_console->Create();
		}

		_3DWorld = _new_VirtualWorld();
		if(!_3DWorld){
			GLL_Throw("Creating VirtualWorld failed");
		}
		_3DWorld->Create();

		_resMgr = _new_ResMgr();
		if(!_resMgr){
			GLL_Throw("Creating ResMgr failed");
		}
		_resMgr->Create();

		_input = _new_Input();
		if(!_input){
			GLL_Throw("Creating Input failed");
		}
		_input->Create(theApp());
	}

	void GameApp::_Start(GameState& startState)
	{
		Init();
		ChangeState( startState );
		_Paused = false;
	}

	void GameApp::Pause()
	{
		_currentGS->Pause();
		_Paused = true;
	}

	void GameApp::Resume()
	{
		_currentGS->Resume();
		_Paused = false;
		TimeMS TSLF = GetTimeInterval();
		TSLF;//time has been paused;
	}

	void GameApp::Update()
	{
		if(_Exit) return;
		if(_Paused) return;
		TimeMS TSLF = GetTimeInterval();
		//释放一些CPU给其他程序
		SlowDownFPS(TSLF);
		SetFPS(TSLF);

		//更新状态
		_currentGS->Update(TSLF);
		//跟新世界
		if(_3DWorld)
		{
			_3DWorld->Update(TSLF);
		}
		//状态是否要求退出
		if(	_currentGS->Ok2ExitGame())
		{
			Shutdown();
		}
	}

	void GameApp::Shutdown()
	{
		//当前状态不容许退出程序
		if(!_currentGS->OnExitGame()) return;
		_currentGS->OnExit();
		Cleanup();
		_Exit = true;
	}

	void GameApp::Cleanup()
	{
		_currentGS = &nullstate;

		_input->Destroy();
		DestorySystem(_input);
		_input = 0;

		_3DWorld->Destory();
		DestorySystem(_3DWorld);
		_3DWorld = 0;

		_resMgr->Destory();
		DestorySystem(_resMgr);
		_resMgr = 0;

		_console->Destory();
		DestorySystem(_console);
		_console = 0;
	}


	GLL::TimeMS GameApp::GetTimeInterval()
	{
		//如果此数为负数，应该给予此玩家某荣誉，如：连续运行客户端49天
		TimeMS ThisTime = _timer.getMilliseconds();
		TimeMS TSLF = 0;

		if(_timeStamp < ThisTime){
			TSLF = ThisTime - _timeStamp;
		}
		_timeStamp = ThisTime;
		return TSLF;
	}

	void GameApp::DestorySystem( System* pSys)
	{
		if(!pSys) return;
		GLL_DEL(pSys);
	}

	void GameApp::SlowDownFPS(TimeMS tslf)
	{
		if( tslf < _maxMS)
		{
			TimeMS interval = _maxMS - tslf;
			Timer::Sleep(interval);
		}
	}

	void GameApp::SetFPS( TimeMS tslf )
	{
		_FPS = 1000.0f / float(tslf);
		_FPSAve = (_FPSAve + _FPS) / 2.0f;
	}

	void GameApp::SetMaxFPS( int  fps)
	{
		_maxMS = TimeMS( 1.0f / float(fps) * 1000.0f );
	}
}//GLL


